const axios = require("axios");
const WinexAuthorizationGenerator = require("../WinexAuthorizationGenerator");

class WinexWardGenerator {

    constructor(redisHost = "127.0.0.1", redisPort = 6379, redisDb = 0) {
        this.redisHost = redisHost;
        this.redisPort = redisPort;
        this.redisDb = redisDb;
        this.authorization = null;
    }

    /**
     * 
     * @returns {Promise<{wardId: string, wardNumber: string, wardName: string}[]>}
     */
    async getWards() {
        const winexAuthorizationGenerator = new WinexAuthorizationGenerator();
        this.authorization = await winexAuthorizationGenerator.getAuthorization("adminAuthorizations");
        const url = `${this.authorization.hostname}/mdm-base/api/v1/app_base_mdm/business_unit_tree/search`;
        const data = JSON.stringify({
            "keyword": "",
            "serviceHospitalSOID": this.authorization.serviceHospitalSOID,
            "buTypeCodes": [
                "399001826"
            ],
            "pageNo": 0,
            "pageSize": 100,
            "total": 100,
            "orgStatus": "",
            "encounterTypeCode": "",
            "hospitalSOID": this.authorization.hospitalSOID
        });
        const config = {
            method: "post",
            maxBodyLength: Infinity,
            url: url,
            headers: {
                "Content-Type": "application/json",
                "Authorization": this.authorization.authorization,
            },
            data: data,
        };
        if (config.url.startsWith("https://")) {
            config.httpsAgent = new (require("https").Agent)({ rejectUnauthorized: false });
        }
        const response = await axios.request(config);
        let wards = response.data.data.map(ward => {
            return {
                wardId: ward.buId,
                wardNumber: ward.buNo,
                wardName: ward.buName
            }
        });
        return wards;
    }

    /**
     * 
     * @param {number} numberOfWards 
     * @param {string} wardNamePrefix 
     * @returns {Promise<{wardId: string, wardNumber: string, wardName: string}[]>}
     */
    async create(numberOfWards = 1, wardNamePrefix = "性能") {
        const winexAuthorizationGenerator = new WinexAuthorizationGenerator();
        this.authorization = await winexAuthorizationGenerator.getAuthorization("adminAuthorizations");
        const wards = [];
        for (let i = 0; i < numberOfWards; i++) {
            let url = `${this.authorization.hostname}/mdm-base/api/v1/app_base_mdm/business_unit/add`;
            let wardNumber = `WARD-${String(i + 1).padStart(3, "0")}-${String(Date.now()).slice(-5)}`;
            let wardName = `${wardNamePrefix}${String(i + 1).padStart(3, "0")}病区`;
            let data = JSON.stringify({
                "buTypeCodes": [
                    "399001826"
                ],
                "encounterTypeList": [
                    {
                        "encounterTypeCode": "145235"
                    }
                ],
                "masterDataCode": "867661",
                "orgName": wardName,
                "orgNo": wardNumber,
                "orgStatus": "98360",
                "pinyin": "",
                "wubi": "",
                "pharmacyServiceFlag": "98176",
                "buTelecomList": null,
                "orgCustomAttributesList": [
                    {
                        "basicDataAttributeConfigId": "399670081",
                        "orgAttributeValue": "98176",
                        "basicDataAttributeNo": "399670081"
                    },
                    {
                        "basicDataAttributeConfigId": "399673093",
                        "orgAttributeValue": "",
                        "basicDataAttributeNo": "399673093"
                    },
                    {
                        "basicDataAttributeConfigId": "399769627",
                        "orgAttributeValue": "98176",
                        "basicDataAttributeNo": "399769627"
                    }
                ],
                "anestheticRoomList": [],
                "hospitalSOID": this.authorization.hospitalSOID,
                "employeeList": [],
                "buCorrelationList": [
                    {
                        "targetOrgId": this.authorization.serviceHospitalSOID,
                        "targetHospitalSOID": this.authorization.serviceHospitalSOID,
                        "targetOrgTypeCode": "152637",
                        "sourceOrgTypeCode": "230267"
                    }
                ],
                "drugStorageLedgerTypeList": [],
                "buContactList": [],
                "clinicalSubjectCodeList": []
            });
            let config = {
                method: "post",
                maxBodyLength: Infinity,
                url: url,
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": this.authorization.authorization,
                },
                data: data,
            };
            if (config.url.startsWith("https://")) {
                config.httpsAgent = new (require("https").Agent)({ rejectUnauthorized: false });
            }
            let response = await axios.request(config);
            const wardId = response.data.data;
            wards.push({
                wardId: wardId,
                wardNumber: wardNumber,
                wardName: wardName
            });
        }
        return wards;
    }

    /**
     * 
     * @param {{wardId: string, wardNumber: string, wardName: string}[]} wards 
     * @param {string} status 
     * @param {{employeeId: string, employeeNumber: string, employeeName: string, hospitalSOID: string, serviceHospitalSOID: string}[]} employees 
     * @returns {Promise<{wardId: string, wardNumber: string, wardName: string}[]>}
     */
    async update(wards, status = "启用", employees = []) {
        switch (status) {
            case "启用":
                status = "98360";
                break;
            case "新增":
                status = "256647";
                break;
            default:
                status = "98360"
                break;
        }
        if (employees && employees.length > 0) {
            employees = employees.map(employee => {
                return {
                    "employeeId": employee.employeeId,
                    "contactFlag": "98176",
                    "adminPositionCodeList": [],
                    "empOrgRoleCodeList": []
                };
            });
        } else {
            employees = [];
        }
        const winexAuthorizationGenerator = new WinexAuthorizationGenerator();
        this.authorization = await winexAuthorizationGenerator.getAuthorization("adminAuthorizations");
        for (let i = 0; i < wards.length; i++) {
            const ward = wards[i];
            let url = `${this.authorization.hostname}/mdm-base/api/v1/app_base_mdm/business_unit/modify`;
            let data = JSON.stringify({
                "orgId": ward.wardId,
                "orgNo": ward.wardNumber,
                "orgName": ward.wardName,
                "buTypeCode": "399001826",
                "buTypeCodes": [
                    "399001826"
                ],
                "orgStatus": status,
                "targetBuId": `${ward.wardNumber},${ward.wardName}"`,
                "targetBuNo": ward.wardNumber,
                "targetBuName": ward.wardName,
                "buTelecomList": null,
                "buCorrelationList": [
                    {
                        "targetOrgId": this.authorization.serviceHospitalSOID,
                        "targetHospitalSOID": this.authorization.serviceHospitalSOID,
                        "targetOrgTypeCode": "152637",
                        "sourceOrgTypeCode": "230267"
                    }
                ],
                "buContactList": [],
                "employeeList": employees,
                "encounterTypeList": [
                    {
                        "encounterTypeCode": "145235"
                    }
                ],
                "drugStorageLedgerTypeList": [],
                "orgCustomAttributesList": [
                    {
                        "basicDataAttributeConfigId": "399670081",
                        "orgAttributeValue": "98176",
                        "basicDataAttributeNo": "399670081"
                    },
                    {
                        "basicDataAttributeConfigId": "399673093",
                        "orgAttributeValue": "",
                        "basicDataAttributeNo": "399673093"
                    },
                    {
                        "basicDataAttributeConfigId": "399769627",
                        "orgAttributeValue": "98176",
                        "basicDataAttributeNo": "399769627"
                    }
                ],
                "anestheticRoomList": [],
                "hospitalSOID": this.authorization.hospitalSOID,
                "masterDataCode": "867661",
                "clinicalSubjectCodeList": []
            })
            let config = {
                method: "post",
                maxBodyLength: Infinity,
                url: url,
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": this.authorization.authorization,
                },
                data: data,
            };
            if (config.url.startsWith("https://")) {
                config.httpsAgent = new (require("https").Agent)({ rejectUnauthorized: false });
            }

            await axios.request(config);
        }
        return wards;
    }

    /**
     * 
     * @param {{wardId: string, wardNumber: string, wardName: string}[]} wards 
     */
    async delete(wards) {
        const winexAuthorizationGenerator = new WinexAuthorizationGenerator();
        this.authorization = await winexAuthorizationGenerator.getAuthorization("adminAuthorizations");
        for (let i = 0; i < wards.length; i++) {
            const ward = wards[i];
            let url = `${this.authorization.hostname}/mdm-base/api/v1/app_base_mdm/business_unit/delete/by_org_ids`;
            let data = JSON.stringify({
                "hospitalSOID": this.authorization.hospitalSOID,
                "orgId": ward.wardId
            });
            let config = {
                method: "post",
                maxBodyLength: Infinity,
                url: url,
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": this.authorization.authorization,
                },
                data: data,
            };
            if (config.url.startsWith("https://")) {
                config.httpsAgent = new (require("https").Agent)({ rejectUnauthorized: false });
            }
            await axios.request(config);
        }
    }

    /**
     * 
     * @returns {Promise<{employeeId: string, employeeNumber: string, employeeName: string, hospitalSOID: string, serviceHospitalSOID: string}[]>}
     */
    async getEmployees() {
        const winexAuthorizationGenerator = new WinexAuthorizationGenerator();
        const inpatientDoctor = (await winexAuthorizationGenerator.getAuthorization("inpatientDoctorAuthorizations")).employee;
        const inpatientNurse = (await winexAuthorizationGenerator.getAuthorization("inpatientNurseAuthorizations")).employee;
        return [inpatientDoctor, inpatientNurse];
    }

    /**
     * 
     * @param {{employeeId: string, employeeNumber: string, employeeName: string, hospitalSOID: string, serviceHospitalSOID: string}} employee 
     * @returns {Promise<{departmentId: string, departmentNumber: string, departmentName: string}[]>}
     */
    async getDepartmentsByEmployee(employee) {
        const winexAuthorizationGenerator = new WinexAuthorizationGenerator();
        this.authorization = await winexAuthorizationGenerator.getAuthorization("adminAuthorizations");
        let url = `${this.authorization.hostname}/inp/encounter-component/api/v1/encounter_component/inpat_org_target/query/by_example`;
        let data = JSON.stringify({
            "buTypeCode": "256002",
            "employeeId": employee.employeeId,
            "hospitalSOID": this.authorization.employee.hospitalSOID
        });
        let config = {
            method: "post",
            maxBodyLength: Infinity,
            url: url,
            headers: {
                "Content-Type": "application/json",
                "Authorization": this.authorization.authorization,
            },
            data: data,
        };
        if (config.url.startsWith("https://")) {
            config.httpsAgent = new (require("https").Agent)({ rejectUnauthorized: false });
        }
        let response = await axios.request(config);
        let departments = response.data.data.filter(department => {
            return department.serviceHospitalSOID === employee.serviceHospitalSOID;
        }).map(department => {
            return {
                departmentId: department.orgId,
                departmentNumber: department.orgNo,
                departmentName: department.orgName,
            }
        });
        return departments;
    }

    /**
     * 
     * @param {{wardId: string, wardNumber: string, wardName: string}} ward 
     * @param {{departmentId: string, departmentNumber: string, departmentName: string}[]} department 
     */
    async setDepartments(ward, departments) {
        const winexAuthorizationGenerator = new WinexAuthorizationGenerator();
        this.authorization = await winexAuthorizationGenerator.getAuthorization("adminAuthorizations");
        for (let i = 0; i < departments.length; i++) {
            const department = departments[i];
            let url = `${this.authorization.hostname}/mdm-base/api/v1/app_base_mdm/business_unit/correlation/bind`;
            let data = JSON.stringify({
                "buRelationTypeCode": "256587",
                "sourceOrgId": department.departmentId,
                "targetHospitalSOID": this.authorization.hospitalSOID,
                "hospitalSOID": this.authorization.hospitalSOID,
                "targetOrgId": ward.wardId
            });
            let config = {
                method: "post",
                maxBodyLength: Infinity,
                url: url,
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": this.authorization.authorization,
                },
                data: data,
            };
            if (config.url.startsWith("https://")) {
                config.httpsAgent = new (require("https").Agent)({ rejectUnauthorized: false });
            }
            await axios.request(config);
        }
    }

}

module.exports = WinexWardGenerator;